package k8s

import (
	"fmt"
	"k8s-operator-test/utils/logs"
	"log"
	"runtime"
	"time"

	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/cert"
)

func CreateK8sApiServerClient(apiServerHost, rootCaFile, kubeConfig string) (*kubernetes.Clientset, error) {
	cfg, err := clientcmd.BuildConfigFromFlags(apiServerHost, kubeConfig)
	if err != nil {
		logs.Debug(err)
		return nil, err
	}
	cfg.UserAgent = fmt.Sprintf(
		"K8s-Operator-Agent:%s/%s/%s",
		runtime.GOOS,
		runtime.GOARCH,
		runtime.Version(),
	)

	if apiServerHost != "" && rootCaFile != "" {
		tlsClientConfig := rest.TLSClientConfig{}
		if _, err := cert.NewPool(rootCaFile); err != nil {
			return nil, err
		} else {
			tlsClientConfig.CAFile = rootCaFile
		}
		cfg.TLSClientConfig = tlsClientConfig
	}

	client, err := kubernetes.NewForConfig(cfg)
	if err != nil {
		return nil, err
	}
	defaultBackOff := wait.Backoff{
		Duration: 1 * time.Second,
		Factor:   1.5,
		Jitter:   0.1,
		Steps:    10,
	}

	retries := 0
	var lastErr error
	// var v *discovery.Info
	err = wait.ExponentialBackoff(defaultBackOff, func() (bool, error) {
		_, lastErr = client.Discovery().ServerVersion()
		if lastErr == nil {
			return true, nil
		}
		retries++
		return false, nil
	})
	if err != nil {
		return nil, lastErr
	}
	if retries > 0 {
		log.Printf("Initial connection to the kubernetes API server walt retry %s times", retries)
	}
	return client, nil
}
